@inherits MiniRazor.TemplateBase<CodeEntity>
@namespace MicroCloud.CodeGeneration.Generates
@using System;
@using System.Collections.Generic;
@using System.Linq;
@using MicroCloud.CodeGeneration
@using MicroCloud.CodeGeneration.Database
@using MicroCloud.CodeGeneration.Dtos
@using MicroCloud.CodeGeneration.Entities
@using MicroCloud.CodeGeneration.Generates
@{
    CodeEntity entity = Model;
    string keyType = TypeHelper.ToSingleTypeName(entity.PrimaryKeyTypeFullName);
}//------------------------------------------------------------------------------
// <auto-generated>
//    此代码由代码生成器生成。
//    如果需要扩展此类：可遵守如下规则进行扩展：
//      1.横向扩展：如需添加额外的映射，可新建文件“@(entity.Name)Configuration.cs”的分部类进行扩展
//</auto-generated>
// -----------------------------------------------------------------------

namespace @(entity.Module.Namespace).EntityConfiguration
{
    /// &lt;summary&gt;
    /// 实体配置类：@(entity.Display)信息
    /// &lt;/summary&gt;
    public partial class @(entity.Name)Configuration : EntityTypeConfigurationBase&lt;@(entity.Name)Entity, @(keyType)&gt;
    {
        /// &lt;summary&gt;
        /// 重写以实现实体类型各个属性的数据库配置
        /// &lt;/summary&gt;
        /// &lt;param name="builder"&gt;实体类型创建器&lt;/param&gt;
        public override void Configure(EntityTypeBuilder&lt;@(entity.Name)Entity&gt; builder)
        {
            @GetTable(entity)
@foreach (var prop in entity.Properties.Where(m => !m.IsNavigation))
{
<text>            @GetProperty(prop)
</text>
}

@foreach (var foreign in entity.Foreigns)
{
<text>            @GetForeign(foreign, entity)
</text>
}
            FK_Nav_Index_Configure(builder);
        }

        /// <summary>
        /// 额外的配置(外键,导航,索引)
        /// </summary>
        partial void FK_Nav_Index_Configure(EntityTypeBuilder&lt;@(entity.Name)Entity&gt; builder);
    }
}

@functions
{
            static string GetTable(CodeEntity entity)
            {
                List<string> list = new List<string>();
                list.Add("builder");

                if (!string.IsNullOrEmpty(entity.Display))
                {
                    list.Add($".ToTable(t => t.HasComment(\"{entity.Display}\"))");
                }

                list.Add(";");
                return list.ExpandAndToString("");
            }

            static string GetProperty(CodeProperty property)
            {
                List<string> list = new List<string>();
                list.Add("builder");

                var sbline = new System.Text.StringBuilder();
                sbline.Append($".Property(a => a.{property.Name})");
                if (!string.IsNullOrEmpty(property.Display))
                {
                    sbline.Append($".HasComment(\"{ property.Display}\")");
                }

                if (!string.IsNullOrEmpty(property.DefaultValue))
                {
                    sbline.Append($".HasDefaultValue({ property.DefaultValue})");
                }

                list.Add(sbline.ToString());
                list.Add(";");
                return list.ExpandAndToString("");
            }

            static string GetForeign(CodeForeign foreign, CodeEntity entity)
            {
                List<string> list = new List<string>();

                list.Add("builder");
                list.Add(Relation(foreign, entity));
                list.Add(";");

                return list.ExpandAndToString("");
            }

            private static string Relation(CodeForeign foreign, CodeEntity entity)
            {
                string line = string.Empty;
                switch (foreign.ForeignRelation)
                {
                    case ForeignRelation.OneToMany:
                        line += ".HasMany";
                        break;
                    case ForeignRelation.ManyToOne:
                        line += ".HasOne";
                        break;
                    case ForeignRelation.OneToOne:
                        line += ".HasOne";
                        break;
                    case ForeignRelation.OwnsOne:
                        line += ".OwnsOne";
                        break;
                    case ForeignRelation.OwnsMany:
                        line += ".OwnsMany";
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }

                if (!string.IsNullOrEmpty(foreign.OtherEntity))
                {
                    line += $"<{TypeHelper.ToSingleTypeName(foreign.OtherEntity)}>";
                }
                line += "(";
                if (!string.IsNullOrEmpty(foreign.SelfNavigation))
                {
                    line += $"m => m.{foreign.SelfNavigation}";
                }
                line += ")";
                switch (foreign.ForeignRelation)
                {
                    case ForeignRelation.OneToMany:
                        line += ".WithOne(";
                        break;
                    case ForeignRelation.ManyToOne:
                        line += ".WithMany(";
                        break;
                    case ForeignRelation.OneToOne:
                        line += ".WithOne(";
                        break;
                    case ForeignRelation.OwnsOne:
                        break;
                    case ForeignRelation.OwnsMany:
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
                if (!new[] { ForeignRelation.OwnsOne, ForeignRelation.OwnsMany }.Contains(foreign.ForeignRelation))
                {
                    if (!string.IsNullOrEmpty(foreign.OtherNavigation))
                    {
                        line += $"n => n.{foreign.OtherNavigation})";
                    }
                    else
                    {
                        line += ")";
                    }
                    if (!string.IsNullOrEmpty(foreign.SelfForeignKey))
                    {
                        line += ".HasForeignKey";
                        if (foreign.ForeignRelation == ForeignRelation.OneToOne)
                        {
                            line += $"<{TypeHelper.ToSingleTypeName(entity.Name)}>";
                        }
                        line += $"(m => m.{foreign.SelfForeignKey})";

                        line += ".SetForeignKey";
                        var isRequired = foreign.IsRequired ? "true" : "false";
                        line += $"(\"{foreign.SelfForeignKey}\",{isRequired})";
                    }
                    if (foreign.DeleteBehavior != null)
                    {
                        line += $".OnDelete(DeleteBehavior.{foreign.DeleteBehavior.Value})";
                    }
                }
                return line;
            }
        }
